package com.example.good.service.impl;

import cn.hutool.extra.cglib.CglibUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.good.entity.ClassDO;
import com.example.good.entity.PageVO;
import com.example.good.entity.StudentDO;
import com.example.good.entity.StudentsVO;
import com.example.good.entity.request.AddStudentToClassRequest;
import com.example.good.entity.request.StudentQueryRequest;
import com.example.good.mapper.ClassMapper;
import com.example.good.mapper.StudentMapper;
import com.example.good.service.StudentService;
import com.example.good.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, StudentDO> implements StudentService {
    
    @Autowired
    StudentMapper studentMapper;
    
    @Autowired
    ClassMapper classMapper;

    @Override
    public Boolean updateStudent(StudentsVO studentDO) {
        LambdaQueryWrapper<StudentDO> wrapperStudent = new LambdaQueryWrapper<>();
        wrapperStudent.eq(StudentDO::getStudentId, studentDO.getStudentId());
        StudentDO student = baseMapper.selectOne(wrapperStudent);
        //获取班级名称
        
        if (Objects.isNull(student)){
            return false;
        }
        student.setStudentName(studentDO.getStudentName());
        student.setSex(studentDO.getSex());
        student.setAge(studentDO.getAge());
        student.setClassId(classMapper.getClassByName(studentDO.getClassName()));
        
        LambdaQueryWrapper<StudentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentDO::getStudentId, student.getStudentId());
        baseMapper.update(student, wrapper);
        return true;
    }

    @Override
    public Boolean deleteStudentFromClass(List<String> studentIds) {
        
        if (!studentIds.isEmpty()) {
            for (String studentId : studentIds) {
                StudentDO student = this.getOneStudentById(studentId);
                if (Objects.nonNull(student)) {
                    student.setClassId(0L);
                    int i = baseMapper.updateById(student);
                    if (i != 1){
                        return false;
                    }
                }else {
                    return false;
                }
            }
            return true;
        }else {
            return false;
        }
        
    }

    @Override
    public List<StudentDO> queryNoClassStudents() {
        return this.getNoClassStudents();
    }

    @Override
    public Boolean addStudentToClass(AddStudentToClassRequest request) {
        
        if (!request.getStudentIds().isEmpty()){
            for (String studentId : request.getStudentIds()){
                StudentDO student = this.getOneStudentById(studentId);
                assert student != null;
                student.setClassId(request.getClassId());
                int i = baseMapper.updateById(student);
                if (i != 1){
                    return false;
                }
            }
            return true;
        }
        return null;
    }

    @Override
    public List<StudentDO> getAllStudentByNameOrStudentId(String str) {
        LambdaQueryWrapper<StudentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StudentDO::getStudentId, str)
                .or().like(StudentDO::getStudentName,str);
        List<StudentDO> studentDOS = baseMapper.selectList(wrapper);
        return studentDOS;
    }

    @Override
    public StudentsVO getStudentsDetail(String studentId) {
        LambdaQueryWrapper<StudentDO> wrapperStudent = new LambdaQueryWrapper<>();
        wrapperStudent.eq(StudentDO::getStudentId, studentId);
        StudentDO studentDO = baseMapper.selectOne(wrapperStudent);
        
        //获取班级名字
        LambdaQueryWrapper<ClassDO> wrapperClass = new LambdaQueryWrapper<>();
        wrapperClass.eq(ClassDO::getId, studentDO.getClassId());
        String className = classMapper.selectOne(wrapperClass).getClassName();

        //注入
        StudentsVO studentsVO = new StudentsVO();
        studentsVO.setStudentName(studentDO.getStudentName());
        studentsVO.setAge(studentDO.getAge());
        studentsVO.setSex(studentDO.getSex());
        studentsVO.setClassName(className);
        studentsVO.setGmtCreated(studentDO.getGmtCreated());
        return studentsVO;
    }

    @Override
    public Boolean deleteStudentByStudentIds(List<String> studentIds) {
        LambdaQueryWrapper<StudentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentDO::getStudentId, studentIds);
        int delete = baseMapper.delete(wrapper);
        if (delete == 1){
            return true;
        }else {
            return false;
        }
    }
    
    @Override
    public PageVO<StudentsVO> getAllStudentPage(StudentQueryRequest request) {
        List<StudentsVO> studentsVOResults = new ArrayList<>();
        LambdaQueryWrapper<StudentDO> wrapperStudent = new LambdaQueryWrapper<>();
        if (request.getClassName() == null){
            studentsVOResults = getOneStudentByStudentName(request.getStudentName());
        }else if (request.getClassName() != null ) {
            studentsVOResults = getStudentsByClassName(request.getClassName(), request.getStudentName());
        }
        PageVO<StudentsVO> page = PageUtils.page(studentsVOResults, request.getCurrentPageIndex(), request.getCurrentPageSize());

        return page;
    }

    /**
     * 根据名字进行模糊查找
     * 
     * @param name
     * @return
     */
    private List<StudentsVO> getOneStudentByStudentName(String name){
        List<StudentsVO> studentsResults = new ArrayList<>();
        List<StudentDO> studentDOS = null;
        LambdaQueryWrapper<StudentDO> wrapperStudent = new LambdaQueryWrapper<>();
        
        if (name == null){
            studentDOS =  baseMapper.selectList(null);
        }else{
            wrapperStudent.like(StudentDO::getStudentName, name);
            studentDOS = baseMapper.selectList(wrapperStudent);
        }

        for (StudentDO studentDO : studentDOS){
            StudentsVO copy = CglibUtil.copy(studentDO, StudentsVO.class);
            //获取班级名称
            copy.setClassName(classMapper.getClassById(studentDO.getClassId()).getClassName());
            studentsResults.add(copy);
        }
        return studentsResults;
    }
    
    private List<StudentsVO> getStudentsByClassName(String className, String studentName){
        
        LambdaQueryWrapper<ClassDO> wrapperClass = new LambdaQueryWrapper<>();
        wrapperClass.like(ClassDO::getClassName, className);
        List<Long> classIds = classMapper.selectList(wrapperClass).stream().map(ClassDO::getId).collect(Collectors.toList());
        LambdaQueryWrapper<StudentDO> wrapperStudent = new LambdaQueryWrapper<>();
        wrapperStudent.in(StudentDO::getClassId, classIds)
                        .like(studentName != null,StudentDO::getStudentName, studentName);
        List<StudentDO> studentLists = baseMapper.selectList(wrapperStudent);

        List<StudentsVO> studentsResults = new ArrayList<>();
        for (StudentDO studentDO : studentLists){
            StudentsVO copy = CglibUtil.copy(studentDO, StudentsVO.class);
            //获取班级名称
            copy.setClassName(classMapper.getClassById(studentDO.getClassId()).getClassName());
            studentsResults.add(copy);
        }
        
        return studentsResults;
    }

    /**
     * 根据id获取学生
     * 
     * @param studentId
     * @return
     */
    private StudentDO getOneStudentById(String studentId){
        LambdaQueryWrapper<StudentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentDO::getStudentId, studentId);
        StudentDO studentDO = baseMapper.selectOne(wrapper);
        if (Objects.nonNull(studentDO)){
            return studentDO;
        }else {
            return null;
        }
    }

    /**
     * 获取没有加入班级的学生
     * 
     * @return
     */
    private List<StudentDO> getNoClassStudents(){
        LambdaQueryWrapper<StudentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentDO::getClassId, 0);
        return baseMapper.selectList(wrapper);
    }
    
    
    
    
}
